package com.gkzf.ai.module.crm.service.creditReport;

import com.gkzf.ai.framework.mybatis.core.query.QueryWrapperX;
import com.gkzf.ai.module.crm.dal.dataobject.creditReport.CreditReportDetailsDO;
import com.gkzf.ai.module.crm.dal.dataobject.creditReport.CreditReportLoanDetailsDO;
import com.gkzf.ai.module.crm.dal.dataobject.creditReport.UserCreditReportAdmittanceConditionDO;
import com.gkzf.ai.module.crm.dal.mysql.creditReport.CreditReportDetailsMapper;
import com.gkzf.ai.module.crm.dal.mysql.creditReport.CreditReportLoanDetailsMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import static com.gkzf.ai.module.crm.util.AnalysisJsonObjectUtils.convertMoney;

/**
 * 收入负债比service实现类
 */
@Slf4j
@Service
public class IncomeDebtRatioServiceImpl implements IncomeDebtRatioService{

    private final CreditReportDetailsMapper detailsMapper;

    private final CreditReportLoanDetailsService creditReportLoanDetailsService;

    private final CreditReportLoanDetailsMapper creditReportLoanDetailsMapper;

    private final CreditReportAdmittanceConditionService creditReportAdmittanceConditionService;

    public IncomeDebtRatioServiceImpl(CreditReportAdmittanceConditionService creditReportAdmittanceConditionService,
                                      CreditReportDetailsMapper detailsMapper,
                                      CreditReportLoanDetailsService creditReportLoanDetailsService, CreditReportLoanDetailsMapper creditReportLoanDetailsMapper) {
        this.creditReportAdmittanceConditionService = creditReportAdmittanceConditionService;
        this.detailsMapper = detailsMapper;
        this.creditReportLoanDetailsService = creditReportLoanDetailsService;
        this.creditReportLoanDetailsMapper = creditReportLoanDetailsMapper;
    }

    /**
     * 获取信用贷款月还款金额
     * @param creditReportDetailsId 征信报告明细id
     *                              公式：o月还款金额：征信报告二次解析中贷款“贷款月还款金额”➕信用卡“已用额度✖️10%”
     *                              贷款月还款金额-所有贷款账户明细中，满足账户状态 未结清、业务种类非个人住房商业贷款，个人住房公积金贷款，担保方式：非抵押，组合 条件的“ 本月应还款”总和
     * @return 月还款金额
     */
    @Override
    public BigDecimal getMonthlyRepaymentAmount(Long creditReportDetailsId) {
        String monthlyRepaymentAmount = "0";
        CreditReportDetailsDO creditReportDetailsDO = detailsMapper.selectById(creditReportDetailsId);
        if (creditReportDetailsDO.getCreditCardUsedCredit().compareTo(BigDecimal.ZERO) > 0){
            // 月还款去余额的百分之10
            monthlyRepaymentAmount = String.valueOf(creditReportDetailsDO.getCreditCardUsedCredit().multiply(BigDecimal.valueOf(0.1)));
        }
        String monthlyRepaymentAmount1 = creditReportLoanDetailsService.getMonthlyRepaymentAmount(creditReportDetailsId);
        BigDecimal added = new BigDecimal(monthlyRepaymentAmount).add(new BigDecimal(monthlyRepaymentAmount1));
        if (added.compareTo(BigDecimal.ZERO) == 0){
            return BigDecimal.ZERO;
        }
        return added.setScale(2, RoundingMode.HALF_UP);
    }


    /**
     * 获取总贷款月还款金额
     * @param creditReportDetailsId 征信报告明细id
     *                              公式：o月还款金额：征信报告二次解析中贷款“贷款月还款金额”➕信用卡“已用额度✖️10%”
     *                              贷款月还款金额-所有贷款账户明细中，满足账户状态 未结清
     * @return 月还款金额
     */
    @Override
    public BigDecimal getTotalMonthlyRepaymentAmount(Long creditReportDetailsId) {
        String monthlyRepaymentAmount = "0";
        CreditReportDetailsDO creditReportDetailsDO = detailsMapper.selectById(creditReportDetailsId);
        if (creditReportDetailsDO.getCreditCardUsedCredit().compareTo(BigDecimal.ZERO) > 0){
            // 月还款去余额的百分之10
            monthlyRepaymentAmount = String.valueOf(creditReportDetailsDO.getCreditCardUsedCredit().multiply(BigDecimal.valueOf(0.1)));
        }
        String monthlyRepaymentAmount1 = creditReportLoanDetailsService.getTotalMonthlyRepaymentAmount(creditReportDetailsId);
        BigDecimal added = new BigDecimal(monthlyRepaymentAmount).add(new BigDecimal(monthlyRepaymentAmount1));
        if (added.compareTo(BigDecimal.ZERO) == 0){
            return BigDecimal.ZERO;
        }
        return added.setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * 获取信用贷款总额
     * 取值方式：征信报告二次解析中负债汇总下的贷款负债-信用贷款信息-“贷款总额”
     * @param creditReportDetailsId  征信报告明细id
     * @return 信用贷款总额
     */
    @Override
    public BigDecimal getTotalCreditLoanAmount(Long creditReportDetailsId) {
        CreditReportDetailsDO creditReportDetailsDO = detailsMapper.selectById(creditReportDetailsId);
        if (null != creditReportDetailsDO){
            return creditReportDetailsDO.getCreditLoanMoneyCount();
        }
        return BigDecimal.ZERO;
    }

    /**
     * 获取年收入
     *  公式：取用户补充信息的“年度收入金额”
     * @param creditReportDetailsId  征信报告明细id
     * @return 年收入
     */
    @Override
    public BigDecimal getAnnualIncome(Long creditReportDetailsId) {
        CreditReportDetailsDO creditReportDetailsDO = detailsMapper.selectById(creditReportDetailsId);
        // 详情不为null
        if (null != creditReportDetailsDO){
            // 获取用户补充信息
            UserCreditReportAdmittanceConditionDO creditReportAdmittanceCondition = creditReportAdmittanceConditionService.getCreditReportAdmittanceCondition(creditReportDetailsDO.getCreditBasicId());
            // 公积金为空去年度收入金额
            return Optional.ofNullable(creditReportAdmittanceCondition.getAnnualIncome()).orElse(BigDecimal.ZERO);
        }
        return BigDecimal.ZERO;
    }

    /**
     * 获取认定月收入
     * 公式：复选框，可多选；类型：个税、社保缴存基数、公积金缴存基数、基于按揭房月供、基于房产市值，月收入多选的话，默认以最大值进行计算
     * @param types @param type 类型 可多选；类型：个税、社保缴存基数、公积金缴存基数、基于按揭房月供、基于房产市值
     * @param creditReportDetailsId  征信报告明细id
     * @return 月收入 (BigDecimal 类型)
     */
    @Override
    public BigDecimal getConcludeMonthlyIncome(Long creditReportDetailsId,String types) {

        // 1. 输入校验
        if (creditReportDetailsId == null || types == null || types.trim().isEmpty()) {
            log.warn("无效输入：creditReportDetailsId={} 或 type 为 null/空", creditReportDetailsId);
            return BigDecimal.ZERO; // 无效输入返回默认值 BigDecimal.ZERO
        }
        // 2. 数据获取
        CreditReportDetailsDO creditReportDetailsDO = detailsMapper.selectById(creditReportDetailsId);
        if (null == creditReportDetailsDO){
            log.warn("未找到 CreditReportDetailsDO，id={}", creditReportDetailsId);
            return BigDecimal.ZERO;
        }
        // 获取用户补充信息
        UserCreditReportAdmittanceConditionDO admittanceConditionDO = creditReportAdmittanceConditionService.getCreditReportAdmittanceCondition(creditReportDetailsDO.getCreditBasicId());
        if (null == admittanceConditionDO){
            log.warn("未找到 UserCreditReportAdmittanceConditionDO，creditBasicId={}", creditReportDetailsDO.getCreditBasicId());
            return BigDecimal.ZERO;
        }

        return getBigDecimal(types, admittanceConditionDO);
    }


    /**
     * 获取 月收入
     * 年收入除以12
     * @param creditReportDetailsId  征信报告明细id
     * @return 月收入 (BigDecimal 类型)
     */
    @Override
    public BigDecimal getMonthlyIncome(Long creditReportDetailsId) {

        // 1. 输入校验
        if (creditReportDetailsId == null) {
            log.warn("无效输入：creditReportDetailsId={} 或 type 为 null/空", creditReportDetailsId);
            return BigDecimal.ZERO; // 无效输入返回默认值 BigDecimal.ZERO
        }
        // 2. 数据获取
        CreditReportDetailsDO creditReportDetailsDO = detailsMapper.selectById(creditReportDetailsId);
        if (null == creditReportDetailsDO){
            log.warn("未找到 CreditReportDetailsDO，id={}", creditReportDetailsId);
            return BigDecimal.ZERO;
        }
        // 获取用户补充信息
        UserCreditReportAdmittanceConditionDO admittanceConditionDO = creditReportAdmittanceConditionService.getCreditReportAdmittanceCondition(creditReportDetailsDO.getCreditBasicId());
        if (null == admittanceConditionDO){
            log.warn("未找到 UserCreditReportAdmittanceConditionDO，creditBasicId={}", creditReportDetailsDO.getCreditBasicId());
            return BigDecimal.ZERO;
        }
        if (Objects.nonNull(admittanceConditionDO.getAnnualIncome()) && admittanceConditionDO.getAnnualIncome().compareTo(BigDecimal.ZERO) > 0){
           // 年收入除以12
            return admittanceConditionDO.getAnnualIncome().divide(BigDecimal.valueOf(12), 2, RoundingMode.HALF_UP);
        }
        return BigDecimal.ZERO;
    }

    /**
     * 月收入
     * @param userOpenId 小程序用户标识
     * @return 月收入
     */
    @Override
    public BigDecimal getAnnualIncome(String userOpenId) {

            // 获取用户补充信息
            UserCreditReportAdmittanceConditionDO creditReportAdmittanceCondition = creditReportAdmittanceConditionService.getCreditReportAdmittanceCondition(null);
            // 为null 返回 0
            if (null == creditReportAdmittanceCondition){
                return BigDecimal.ZERO;
            }
            // 公积金为空去年度收入金额
            return Optional.ofNullable(creditReportAdmittanceCondition.getAnnualIncome()).orElse(BigDecimal.ZERO);
        }


    /**
     * 月收入
     * @param userOpenId 小程序用户标识
     * @param types 类型 可多选；类型：个税、社保缴存基数、公积金缴存基数、基于按揭房月供、基于房产市值
     * @return 月收入
     */
    @Override
    public BigDecimal getMonthlyIncome(String userOpenId, String types) {
        // 获取用户补充信息
        UserCreditReportAdmittanceConditionDO admittanceCondition = creditReportAdmittanceConditionService.getCreditReportAdmittanceCondition(null);
        return getBigDecimal(types, admittanceCondition);
    }


    /**
     * @param types 取值类型
     * @param admittanceConditionDO 补充信息
     * @return 月收入
     */
    private static BigDecimal getBigDecimal(String types, UserCreditReportAdmittanceConditionDO admittanceConditionDO) {
        // 3. 类型解析并收集所有类型的收入
        String[] typeList = types.split(",");
        final int scale = 2; // 用于最终输出格式化和潜在的中间计算精度
        List<BigDecimal> allCalculatedIncomes = new ArrayList<>(); // 收集所有有效计算结果的列表

        for (String singleType : typeList) {
            String trimmedType = singleType.trim();
            BigDecimal incomeForThisType = null; // 用于暂存当前类型计算出的收入

            incomeForThisType = getBigDecimal(admittanceConditionDO, trimmedType, incomeForThisType, scale);

            // 如果当前类型计算出了一个非空的收入值，就添加到总列表中
            if (incomeForThisType != null) {
                allCalculatedIncomes.add(incomeForThisType);
            }
        }

        return getBigDecimal(types, allCalculatedIncomes);
    }

    /**
     * 根据类型计算收入
     * @param admittanceConditionDO 补充信息
     * @param trimmedType 类型
     * @param incomeForThisType 当前类型计算出的收入
     * @param scale 输出精度
     * @return 月收入
     */
    private static BigDecimal getBigDecimal(UserCreditReportAdmittanceConditionDO admittanceConditionDO, String trimmedType, BigDecimal incomeForThisType, int scale) {
        // 根据类型计算收入
        switch (trimmedType) {
            case "个税" -> {
                // 月收入-个税：年度收入金额➗12
                // 年收入不为空 并且 大于0
                if (null != admittanceConditionDO.getAnnualIncome() && admittanceConditionDO.getAnnualIncome().compareTo(BigDecimal.ZERO) > 0) {
                    incomeForThisType = admittanceConditionDO.getAnnualIncome().divide(BigDecimal.valueOf(12), scale, RoundingMode.HALF_UP);
                }
            }
            case "公积金缴存基数" -> {
                // 月收入-公积金缴存基数：用户填写公积金缴存基数
                if (null != admittanceConditionDO.getCreditReportFundBase()) {
                    // 注意：如果 getCreditReportFundBase() 返回的是 Double，这里转换是标准做法
                    incomeForThisType = BigDecimal.valueOf(admittanceConditionDO.getCreditReportFundBase());
                }
            }
            case "社保缴存基数" -> {

            if (null != admittanceConditionDO.getCreditReportSocialBase()) {
                // 注意：如果 getCreditReportSocialBase() 返回的是 Double，这里转换是标准做法
                incomeForThisType = BigDecimal.valueOf(admittanceConditionDO.getCreditReportSocialBase());
            }
            }
            case "基于房产市值" -> {
                //用户填写全款房、按揭房的房产市值评估金额（两个值都有的话，默认以最大值进行计算）
                BigDecimal mortgageValue = admittanceConditionDO.getMortgageValue();
                BigDecimal fullPaymentValue = admittanceConditionDO.getFullPaymentValue();

                if (mortgageValue != null && fullPaymentValue != null) {
                    incomeForThisType = mortgageValue.max(fullPaymentValue); // 使用 BigDecimal 自带的 max 方法
                } else if (mortgageValue != null) {
                    incomeForThisType = mortgageValue;
                } else if (fullPaymentValue != null) {
                    incomeForThisType = fullPaymentValue;
                }
                // 如果两个值都为 null，incomeForThisType 仍为 null
            }
            case "基于按揭房月供" ->
                // ... 计算逻辑 取补充信息的按揭房月供...
                incomeForThisType = new BigDecimal(Optional.ofNullable(admittanceConditionDO.getMortgageMonthlyPayment()).orElse("0"));

            default -> {
                log.warn("未知或未处理的月收入类型: {}", trimmedType);
            }
        }
        return incomeForThisType;
    }

    /**
     * 从所有收入中找出最大值
     * @param types 类型
     * @param allCalculatedIncomes 所有收入
     * @return 最大值
     */
    private static BigDecimal getBigDecimal(String types, List<BigDecimal> allCalculatedIncomes) {
        // 4. 从收集到的所有收入中找出最大值
        if (allCalculatedIncomes.isEmpty()) {
            // 如果没有一个类型计算出有效收入
            log.info("未从指定类型中计算出任何有效月收入。 types: {}", types);
            return BigDecimal.ZERO;
        } else {
            // 使用 Stream API 找出最大值，更安全地处理潜在的空Optional (尽管这里allCalculatedIncomes不为空)
            // 或者使用 Collections.max(allCalculatedIncomes)
            return allCalculatedIncomes.stream()
                    .max(BigDecimal::compareTo)
                    .orElse(BigDecimal.ZERO);
        }
    }


    @Override
    public String getBalanceTotalByDetailsIdAndInstitution(Long creditReportDetailsId,String institutionName) {
        QueryWrapperX<CreditReportLoanDetailsDO> wrapper = new QueryWrapperX<>();
        wrapper.select("SUM( balance ) AS balance " ); // 指定需要聚合的列
        wrapper.eq("credit_report_details_id", creditReportDetailsId); // 指定查询条件
        wrapper.eq("lending_institution_name",institutionName); // 指定查询条件
        List<CreditReportLoanDetailsDO> creditReportCreditCardDetailsDOS = creditReportLoanDetailsMapper.selectList(wrapper);
        if(Objects.nonNull(creditReportCreditCardDetailsDOS) && !creditReportCreditCardDetailsDOS.isEmpty()) {
            if (null == creditReportCreditCardDetailsDOS.get(0)){
                return "0";
            }
            return convertMoney(creditReportCreditCardDetailsDOS.get(0).getBalance());
        }
        return "0";
    }
}
